/*
 * Created on 2005-3-12
 *
 */
package bma.common.langutil.bean.impl;

import java.lang.reflect.Method;

import bma.common.langutil.bean.AccessType;
import bma.common.langutil.bean.BeanMap;
import bma.common.langutil.core.DirectInvoker;
import bma.common.langutil.core.ExceptionUtil;

/**
 * 
 * @author guanzhong
 * @since 1.0 (imported from BMA.ESP Project)
 */
public class BeanMapSimple extends BeanMapAbstract implements BeanMap {

	private Method getMethod;

	private Method setMethod;

	private Method removeMethod;

	private Method sizeMethod;

	private Method keysMethod;

	public BeanMapSimple(Class prototype) {
		super(prototype);
	}

	@Override
	public boolean accessible(AccessType type) {

		switch (type) {
		case MAP_GET:
			return getMethod != null;
		case SIZE:
			return sizeMethod != null;
		case MAP_REMOVE:
			return removeMethod != null;
		case MAP_SET:
			return setMethod != null;
		case MAP_KEYS:
			return keysMethod != null;
		default:
			return false;
		}
	}

	@Override
	public Object get(Object thisObject, String key) {
		if (thisObject == null) {
			throw new NullPointerException("this object");
		}
		if (getMethod == null) {
			throw new NullPointerException("getMap[" + getPrototype() + "]");
		}

		try {
			return DirectInvoker.invoke(thisObject, getMethod,
					new Object[] { key });

		} catch (Exception e) {
			throw ExceptionUtil.throwRuntime(e);
		}
	}

	@Override
	public int size(Object thisObject) {
		if (thisObject == null) {
			throw new NullPointerException("this object");
		}
		if (sizeMethod == null) {
			throw new NullPointerException("size[" + getPrototype() + "]");
		}

		try {
			return ((Integer) DirectInvoker
					.invoke(thisObject, sizeMethod, null)).intValue();
		} catch (Exception e) {
			throw ExceptionUtil.throwRuntime(e);
		}
	}

	@Override
	public void remove(Object thisObject, String key) {
		if (thisObject == null) {
			throw new NullPointerException("this object");
		}
		if (removeMethod == null) {
			throw new NullPointerException("remove[" + getPrototype() + "]");
		}

		try {
			DirectInvoker
					.invoke(thisObject, removeMethod, new Object[] { key });
		} catch (Exception e) {
			throw ExceptionUtil.throwRuntime(e);
		}

	}

	@Override
	public void set(Object thisObject, String key, Object value) {
		if (thisObject == null) {
			throw new NullPointerException("this object");
		}
		if (setMethod == null) {
			throw new NullPointerException("set[" + getPrototype() + "]");
		}

		try {
			DirectInvoker.invoke(thisObject, setMethod, new Object[] { key,
					value });
		} catch (Exception e) {
			throw ExceptionUtil.throwRuntime(e);
		}
	}

	@Override
	public String[] keys(Object thisObject) {
		if (thisObject == null) {
			throw new NullPointerException("this object");
		}
		if (keysMethod == null) {
			throw new NullPointerException("keys[" + getPrototype() + "]");
		}

		try {
			return (String[]) DirectInvoker
					.invoke(thisObject, keysMethod, null);
		} catch (Exception e) {
			throw ExceptionUtil.throwRuntime(e);
		}
	}

	/**
	 * @return Returns the getMethod.
	 */
	public Method getGetMethod() {
		return getMethod;
	}

	/**
	 * @param getMethod
	 *            The getMethod to set.
	 */
	public void setGetMethod(Method getMethod) {
		this.getMethod = getMethod;
	}

	/**
	 * @return Returns the removeMethod.
	 */
	public Method getRemoveMethod() {
		return removeMethod;
	}

	/**
	 * @param removeMethod
	 *            The removeMethod to set.
	 */
	public void setRemoveMethod(Method removeMethod) {
		this.removeMethod = removeMethod;
	}

	/**
	 * @return Returns the setMethod.
	 */
	public Method getSetMethod() {
		return setMethod;
	}

	/**
	 * @param setMethod
	 *            The setMethod to set.
	 */
	public void setSetMethod(Method setMethod) {
		this.setMethod = setMethod;
	}

	/**
	 * @return Returns the sizeMethod.
	 */
	public Method getSizeMethod() {
		return sizeMethod;
	}

	/**
	 * @param sizeMethod
	 *            The sizeMethod to set.
	 */
	public void setSizeMethod(Method sizeMethod) {
		this.sizeMethod = sizeMethod;
	}

	/**
	 * @return Returns the keysMethod.
	 */
	public Method getKeysMethod() {
		return keysMethod;
	}

	/**
	 * @param keysMethod
	 *            The keysMethod to set.
	 */
	public void setKeysMethod(Method keysMethod) {
		this.keysMethod = keysMethod;
	}

}
